package com.etone.smartAudit.utils;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * @author: 蒋学伟
 * @create: 2020-07-10 18:21:14
 * @Description 验证码
 */
public class VerifyUtil {

    /**
     * 随机数基础库
     */
    //private static final String randStr = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String randStr = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";

    /**
     * 最大复杂度
     */
    private static final int maxComplexity = 10;

    private static Random random = new Random();


    /**
     * @param response
     * @param width      图片长度
     * @param complexity 验证码复杂度
     * @return
     */
    public static String createVerify(HttpServletResponse response, int width, int complexity) {
        int height = width / 3;
        int codeSize = 4;
        //设置相应类型,告诉浏览器输出的内容为图片
        response.setContentType("image/png");
        //设置响应头信息，告诉浏览器不要缓存此内容
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expire", 0);
        String randCode = createRand(codeSize);

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        // 产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
        Graphics2D g = image.createGraphics();

        //画干扰
        drawInterfere(g, width, height, complexity);

        //画字符
        drawRandStr(randCode, g, width, height);
        g.dispose();
        try {
            ImageIO.write(image, "png", response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return randCode;
    }

    /**
     * 画随机数
     *
     * @param code
     * @param g
     * @param width
     * @param height
     */
    private static void drawRandStr(String code, Graphics g, int width, int height) {
        //干扰线数量
        int lineSize = height / 3;
        for (int j = 0; j < lineSize; j++) {
            g.setFont(new Font("雅黑", Font.BOLD, Math.round(height * 0.8f)));
            FontMetrics metrics = g.getFontMetrics(g.getFont());
            int y = ((height - metrics.getHeight()) / 2) + metrics.getAscent();
            for (int i = 0; i < code.length(); i++) {
                String indexCode = code.charAt(i) + "";
                g.setColor(randColor());
                g.drawString(indexCode, Math.round(width * 0.1f) + Math.round(width * 0.8f / code.length()) * i, y);
            }
        }
    }

    /**
     * 画干扰线
     *
     * @param g
     * @param width
     * @param height
     * @param complexity 复杂度
     */
    private static void drawInterfere(Graphics g, int width, int height, int complexity) {
        complexity = complexity > maxComplexity ? maxComplexity : complexity;
        if (complexity > 0) {
            for (int j = 0; j < height / Math.max(1, maxComplexity - complexity + 0f) * (maxComplexity + complexity + 0f) / maxComplexity; j++) {


                if (complexity > maxComplexity * 0.4) {
                    for (int i = 0; i < Math.ceil(complexity / (maxComplexity * 0.4f)) - 1; i++) {
                        int x = random.nextInt(width);
                        int y = random.nextInt(height);
                        int xl = random.nextInt(Math.round(width * 0.8f));
                        int yl = random.nextInt(Math.round(height * 0.8f));
                        g.setColor(randColor());
                        g.drawLine(x, y, xl, yl);
                    }
                }


                for (int i = 0; i < Math.ceil(complexity / (maxComplexity * 0.2f)); i++) {
                    //干扰圆直径
                    int diameter = random.nextInt(Math.max(Math.round(height * 0.1f), 1));
                    g.setColor(randColor());
                    g.fillOval(random.nextInt(width), random.nextInt(height), diameter, diameter);
                }
                if (complexity > maxComplexity * 0.6) {
                    for (int i = 0; i < Math.ceil(complexity / (maxComplexity * 0.6f)) - 1; i++) {
                        g.setFont(new Font("雅黑", Font.PLAIN, Math.max(2, random.nextInt(Math.round(height * 0.4f - (maxComplexity - complexity) / maxComplexity * 0.1f)))));
                        g.drawString(randStr.charAt(random.nextInt(randStr.length())) + "", random.nextInt(width), random.nextInt(height));
                    }
                }
            }
        }
    }


    /**
     * 获取随机颜色
     *
     * @return
     */
    private static Color randColor() {
        int r = random.nextInt(255);
        int g = random.nextInt(255);
        int b = random.nextInt(255);
        return new Color(r, g, b);
    }

    /**
     * 创建一个随机数
     *
     * @param size
     * @return
     */
    private static String createRand(int size) {
        if (size < 1) {

        }
        String code = "";
        //创建随机数
        for (int i = 0; i < size; i++) {
            char randChar = randStr.charAt(random.nextInt(randStr.length()));
            code += randChar;
        }
        return code;
    }

}
